package org.sauceggplant.item.man.dao;

import com.alibaba.fastjson2.JSON;
import org.sauceggplant.item.man.dto.SqlDto;
import org.sauceggplant.item.man.dto.TypeDto;
import org.sauceggplant.item.man.po.Type;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TypeDao extends AbstractDao {

    private static final Logger logger = LoggerFactory.getLogger(TypeDao.class);

    private static final String INSERT_SQL = "insert into `t_type` (`uuid`,`createAccount`,`updateAccount`,`createTime`,`updateTime`,`version`,`parentId`,`name`) values (?,?,?,?,?,?,?,?)";

    private static final String UPDATE_SQL = "update `t_type` set `version` = ? , `updateTime` = ? ";
    private static final String UPDATE_SQL_END = " where `id` = ? and `version` = ? ";

    private static final String DELETE_SQL = "delete from `t_type` where `id` = ?";

    private static final String SELECT_SQL = "select `id`,`uuid`,`createAccount`,`updateAccount`,`createTime`,`updateTime`,`version`,`parentId`,`name` from `t_type`";

    public List<Type> findAll(TypeDto typeDto, String dbType) throws SQLException {
        SqlDto sqlDto = new SqlDto();
        List<Object> params = new ArrayList<>();
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(SELECT_SQL);
        int condition = 0;
        if (null != typeDto.getNameIsLike()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `name` like ? ");
            params.add("%" + typeDto.getNameIsLike() + "%");
            ++condition;
        }
        if (null != typeDto.getCreateTimeBefore()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `createTime` < ? ");
            params.add(typeDto.getCreateTimeBefore());
            ++condition;
        }
        if (null != typeDto.getCreateTimeAfter()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `createTime` > ? ");
            params.add(typeDto.getCreateTimeAfter());
            ++condition;
        }
        if (null != typeDto.getUpdateTimeBefore()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `updateTime` < ? ");
            params.add(typeDto.getUpdateTimeBefore());
            ++condition;
        }
        if (null != typeDto.getUpdateTimeAfter()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `updateTime` > ? ");
            params.add(typeDto.getUpdateTimeAfter());
            ++condition;
        }
        if (null != typeDto.getUuid()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `uuid` = ? ");
            params.add(typeDto.getUuid());
            ++condition;
        }
        if (null != typeDto.getCreateAccount()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `createAccount` = ? ");
            params.add(typeDto.getCreateAccount());
            ++condition;
        }
        if (null != typeDto.getUpdateAccount()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `updateAccount` = ? ");
            params.add(typeDto.getUpdateAccount());
            ++condition;
        }
        if (null != typeDto.getCreateTime()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `createTime` = ? ");
            params.add(typeDto.getCreateTime());
            ++condition;
        }
        if (null != typeDto.getUpdateTime()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `updateTime` = ? ");
            params.add(typeDto.getUpdateTime());
            ++condition;
        }
        if (null != typeDto.getVersion()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `version` = ? ");
            params.add(typeDto.getVersion());
            ++condition;
        }
        if (null != typeDto.getName()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `name` = ? ");
            params.add(typeDto.getName());
            ++condition;
        }
        if (null != typeDto.getParentId()) {
            if (condition == 0) {
                stringBuffer.append(" where");
            } else {
                stringBuffer.append(" and");
            }
            stringBuffer.append(" `parentId` = ? ");
            params.add(typeDto.getParentId());
            ++condition;
        }
        if (null != typeDto.getOrder()) {
            stringBuffer.append(" order by ? ");
            params.add(typeDto.getOrder());
        }
        if (null != typeDto.getOffset()) {
            stringBuffer.append(" limit ?,? ");
            params.add(typeDto.getOffset());
            params.add(typeDto.getSize());
        }
        sqlDto.setParams(params);
        sqlDto.setType(dbType);
        sqlDto.setSql(stringBuffer.toString());
        getLogger().info(JSON.toJSONString(sqlDto));
        ResultSet resultSet = sqlExecuteService.executeQuery(sqlDto);
        return buildTypeList(resultSet);
    }

    public List<Type> buildTypeList(ResultSet resultSet) throws SQLException {
        List<Type> typeList = new ArrayList<>();
        while (resultSet.next()) {
            Type type = new Type();
            type.setId(resultSet.getLong(1));
            type.setUuid(resultSet.getLong(2));
            type.setCreateAccount(resultSet.getString(3));
            type.setUpdateAccount(resultSet.getString(4));
            type.setCreateTime(resultSet.getTime(5));
            type.setUpdateTime(resultSet.getTime(6));
            type.setVersion(resultSet.getInt(7));
            type.setParentId(resultSet.getLong(8));
            type.setName(resultSet.getString(9));
            typeList.add(type);
        }
        getLogger().debug("findAll.type.res:{}", JSON.toJSONString(typeList));
        return typeList;
    }

    public int insert(Type type, String dbType) throws SQLException {
        SqlDto sqlDto = new SqlDto();
        sqlDto.setType(dbType);
        sqlDto.setSql(INSERT_SQL);
        List<Object> params = new ArrayList<Object>();
        params.add(type.getUuid());
        params.add(type.getCreateAccount());
        params.add(type.getUpdateAccount());
        params.add(type.getCreateTime());
        params.add(type.getUpdateTime());
        params.add(type.getVersion());
        params.add(type.getParentId());
        params.add(type.getName());
        sqlDto.setParams(params);
        return insert(sqlDto);
    }

    public int update(Type type, String dbType) throws SQLException {
        SqlDto sqlDto = new SqlDto();
        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append(UPDATE_SQL);
        List<Object> params = new ArrayList<Object>();
        params.add(type.getVersion() + 1);
        params.add(new Date());
        if (null != type.getUuid()) {
            params.add(type.getUuid());
            stringBuffer.append(", `uuid` = ? ");
        }
        if (null != type.getUpdateAccount()) {
            params.add(type.getUpdateAccount());
            stringBuffer.append(", `updateAccount` = ?");
        }
        if (null != type.getParentId()) {
            params.add(type.getParentId());
            stringBuffer.append(", `parentId` = ?");
        }
        if (null != type.getName()) {
            params.add(type.getName());
            stringBuffer.append(", `name` = ?");
        }
        params.add(type.getId());
        params.add(type.getVersion());
        sqlDto.setParams(params);
        stringBuffer.append(UPDATE_SQL_END);
        sqlDto.setSql(stringBuffer.toString());
        sqlDto.setType(dbType);
        return update(sqlDto);
    }

    public int delete(Long id, String dbType) throws SQLException {
        SqlDto sqlDto = new SqlDto();
        sqlDto.setSql(DELETE_SQL);
        sqlDto.setType(dbType);
        List<Object> params = new ArrayList<Object>();
        params.add(id);
        sqlDto.setParams(params);
        return update(sqlDto);
    }

    @Override
    protected Logger getLogger() {
        return logger;
    }
}
